package com.soul.quartz.ssm.service.impl;

import com.soul.quartz.ssm.bean.JobEntity;
import com.soul.quartz.ssm.service.QuartzService;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class QuartzServiceImpl implements QuartzService {

    @Autowired
    private Scheduler scheduler;

    /**
     * 列表展示
     * @return
     * @throws SchedulerException
     */
    @Override
    public List<JobEntity> jobList() throws SchedulerException {
        List<JobEntity> list = new ArrayList<>();

        List<String> triggerGroupNames = scheduler.getTriggerGroupNames();
        for (String triggerGroup : triggerGroupNames) {
            Set<TriggerKey> triggerKeys = scheduler.getTriggerKeys(GroupMatcher.groupEquals(triggerGroup));
            for (TriggerKey tk : triggerKeys) {
                JobEntity job = new JobEntity();

                Trigger trigger = scheduler.getTrigger(tk);
                if (trigger instanceof CronTrigger){
                    CronTrigger tg = (CronTrigger) trigger;
                    JobKey jobKey = tg.getJobKey();
                    JobDetail jd = scheduler.getJobDetail(jobKey);

                    job.setJobName(jobKey.getName());
                    job.setJobGroup(jobKey.getGroup());
                    job.setJobClass(jd.getJobClass().getSimpleName());
                    job.setTriggerGroup(tk.getGroup());
                    job.setTriggerName(tk.getName());
                    job.setPreviousFireTime(tg.getPreviousFireTime());
                    job.setNextFireTime(tg.getNextFireTime());
                    job.setCron(tg.getCronExpression());
                    job.setStartTime(tg.getStartTime());
                    job.setEndTime(tg.getEndTime());
                    job.setJobStatus(scheduler.getTriggerState(tk).toString());
                    JobDataMap map = tg.getJobDataMap();
                    map.putAll(jd.getJobDataMap());
                    job.setJobDataMap(map.getWrappedMap());
                    list.add(job);
                }
            }
        }
        return list;
    }

    /**
     * 添加一个任务
     * @param cron cron表达式
     * @param cls 执行类
     * @param jobName 任务名称
     * @param jobGroup 任务组
     * @param triggerName 触发器名称
     * @param triggerGroup 触发器组
     */
    @Override
    public void add(String cron, Class cls, String jobName, String jobGroup, String triggerName, String triggerGroup) throws SchedulerException {
        //创建任务
        JobDetail job = JobBuilder.newJob(cls).withIdentity(jobName,jobGroup).build();
        //创建触发器
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName,triggerGroup)
                .withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();
        //关联任务和触发器
        scheduler.scheduleJob(job,trigger);
        //启动
        if (scheduler.isShutdown()) {
            scheduler.start();
        }
    }

    /**
     * 根据jobkey获取对应的任务
     * @param jobKey
     * @return
     * @throws SchedulerException
     */
    @Override
    public Map<String, String> getJob(JobKey jobKey) throws SchedulerException {
        Map<String, String> res = new HashMap<>();
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        List<CronTrigger> triggers = (List<CronTrigger>) scheduler.getTriggersOfJob(jobKey);
        if(triggers != null && triggers.size() > 0){
            CronTrigger trigger = triggers.get(0);
            res.put("cron",trigger.getCronExpression());
            res.put("triggerName",trigger.getKey().getName());
            res.put("triggerGroup",trigger.getKey().getGroup());
        }
        res.put("jobName",jobKey.getName());
        res.put("jobGroup",jobKey.getGroup());
        res.put("clazz",jobDetail.getJobClass().getSimpleName());
        return res;
    }

    /**
     * 更新任务
     * @param oldJobName 旧的任务名称
     * @param oldJobGroup 旧的任务组
     * @param oldTriggerName 旧的触发器名称
     * @param oldTriggerGroup 旧的触发器组
     * @param cron cron表达式
     * @param cls 执行类
     * @param jobName 任务名称
     * @param jobGroup 任务组
     * @param triggerName 触发器名称
     * @param triggerGroup 触发器组
     * @return bool
     * @throws SchedulerException
     */
    @Override
    public boolean updateJob(String oldJobName, String oldJobGroup, String oldTriggerName,
                             String oldTriggerGroup, String jobName, String jobGroup,
                             String triggerName, String triggerGroup, String cron, Class cls) throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey(oldTriggerName, oldTriggerGroup);
        Trigger trigger = scheduler.getTrigger(triggerKey);
        if (trigger == null){
            return false;
        }
        JobKey jobKey = JobKey.jobKey(oldJobName, oldJobGroup);
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail == null){
            return false;
        }
        scheduler.pauseTrigger(triggerKey);
        scheduler.unscheduleJob(triggerKey);
        scheduler.deleteJob(jobKey);
        add(cron,cls,jobName,jobGroup,triggerName,triggerGroup);
        return true;
    }

    @Override
    public void pause(String jobName, String jobGroup) throws SchedulerException {
        scheduler.pauseJob(JobKey.jobKey(jobName,jobGroup));
    }

    @Override
    public void resume(String jobName, String jobGroup) throws SchedulerException {
        scheduler.resumeJob(JobKey.jobKey(jobName,jobGroup));
    }

    @Override
    public void delete(String jobName, String jobGroup, String triggerName, String triggerGroup) throws SchedulerException {
        scheduler.pauseTrigger(TriggerKey.triggerKey(triggerName, triggerGroup));
        scheduler.unscheduleJob(TriggerKey.triggerKey(triggerName, triggerGroup));
        scheduler.deleteJob(JobKey.jobKey(jobName, jobGroup));
    }

}
